import tkinter as tk
from tkinter import ttk, font
import threading
import time
import asyncio
import sys
import re
from fly_client import MCPClient
from connect_factory import ServerManager

# 全局变量
manager = None
client = None
loop = None

# 初始化事件循环和客户端的函数
def async_init_client():
    global manager, client, loop
    
    # 创建新的事件循环
    loop = asyncio.new_event_loop()
    asyncio.set_event_loop(loop)
    
    try:
        # 初始化MCP客户端
        manager = ServerManager()
        client = MCPClient(manager)
        
        # 在事件循环中执行初始化
        async def init_manager():
            await manager.initialize()
            return "初始化完成"
            
        # 执行初始化并等待完成
        result = loop.run_until_complete(init_manager())
        print("MCP客户端初始化完成")
        
        # 启动事件循环
        loop.run_forever()
    except Exception as e:
        print(f"初始化错误: {str(e)}")
    finally:
        if loop and loop.is_running():
            loop.stop()

# 启动后台线程运行事件循环和初始化
init_thread = threading.Thread(target=async_init_client, daemon=True)
init_thread.start()

# 给初始化一些时间
time.sleep(1)

class FlySearchApp:
    def __init__(self, root):
        self.root = root
        self.root.title("航班查询智能体")
        self.root.geometry("600x500")  # 增加高度以显示更多内容
        self.root.resizable(True, True)
        
        # 创建主框架
        self.main_frame = ttk.Frame(root, padding="10")
        self.main_frame.pack(fill=tk.BOTH, expand=True)
        
        # 创建搜索框架
        self.search_frame = ttk.Frame(self.main_frame)
        self.search_frame.pack(fill=tk.X, pady=10)
        
        # 搜索输入框
        self.search_label = ttk.Label(self.search_frame, text="请输入查询条件:")
        self.search_label.pack(side=tk.LEFT, padx=(0, 5))
        
        self.search_entry = ttk.Entry(self.search_frame, width=40)
        self.search_entry.pack(side=tk.LEFT, padx=5)
        
        # 搜索按钮
        self.search_button = ttk.Button(self.search_frame, text="查询", command=self.start_search)
        self.search_button.pack(side=tk.LEFT, padx=5)
        
        # 结果显示区域
        self.result_frame = ttk.LabelFrame(self.main_frame, text="查询结果", padding="10")
        self.result_frame.pack(fill=tk.BOTH, expand=True, pady=10)
        
        # 进度条
        self.progress_frame = ttk.Frame(self.result_frame)
        self.progress_frame.pack(fill=tk.X, pady=10)
        self.progress_frame.pack_forget()  # 初始隐藏
        
        self.progress_label = ttk.Label(self.progress_frame, text="正在查询中...")
        self.progress_label.pack(side=tk.LEFT, padx=5)
        
        self.progress_bar = ttk.Progressbar(self.progress_frame, mode="indeterminate", length=400)
        self.progress_bar.pack(side=tk.LEFT, padx=5, fill=tk.X, expand=True)
        
        # 结果文本区域 - 使用Text而不是Label以支持富文本
        self.result_text = tk.Text(self.result_frame, height=20, width=70, wrap=tk.WORD)
        self.result_text.pack(fill=tk.BOTH, expand=True)
        
        # 设置不同的文本标签
        self.result_text.tag_configure("bold", font=font.Font(weight="bold"))
        self.result_text.tag_configure("italic", font=font.Font(slant="italic"))
        self.result_text.tag_configure("header", font=font.Font(size=12, weight="bold"))
        self.result_text.tag_configure("normal", font=font.Font(family="Arial", size=10))
        
        # 添加滚动条
        scrollbar = ttk.Scrollbar(self.result_text, command=self.result_text.yview)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.result_text.config(yscrollcommand=scrollbar.set)
        
        # 状态信息
        self.status_label = ttk.Label(self.main_frame, text="正在初始化MCP客户端...")
        self.status_label.pack(pady=5)
        
        # 定时检查客户端状态
        self.check_client_status()
        
        # 关闭窗口时清理资源
        self.root.protocol("WM_DELETE_WINDOW", self.on_closing)
    
    def check_client_status(self):
        """检查客户端状态"""
        global client
        if client is not None:
            self.status_label.config(text="MCP客户端初始化完成")
        else:
            # 每500毫秒检查一次
            self.root.after(500, self.check_client_status)
            
    def start_search(self):
        """开始搜索，显示加载进度条"""
        global client
        
        search_query = self.search_entry.get()
        if not search_query:
            self.result_text.delete(1.0, tk.END)
            self.result_text.insert(tk.END, "请输入查询条件")
            return
        
        # 检查客户端是否初始化完成
        if client is None:
            self.result_text.delete(1.0, tk.END)
            self.result_text.insert(tk.END, "MCP客户端尚未初始化完成，请稍后再试")
            return
        
        # 清空之前的结果
        self.result_text.delete(1.0, tk.END)
        
        # 显示进度条
        self.progress_frame.pack(fill=tk.X, pady=10)
        self.progress_bar.start(10)
        
        # 禁用搜索按钮
        self.search_button.config(state="disabled")
        
        # 创建线程进行后台查询
        search_thread = threading.Thread(target=self.perform_search, args=(search_query,))
        search_thread.daemon = True
        search_thread.start()
    
    def perform_search(self, query):
        """调用MCP客户端执行查询"""
        global client, loop
        
        if loop is None or client is None:
            self.root.after(0, lambda: self.update_results(["客户端或事件循环未初始化"]))
            return
            
        try:
            # 创建一个Future来存储结果
            result_future = asyncio.run_coroutine_threadsafe(client.execute(query), loop)
            
            # 获取结果（带超时）
            try:
                result = result_future.result(timeout=120.0)  # 120秒超时
                
                # 处理结果
                if result:
                    results = result.split('\n')
                else:
                    results = ["未找到相关信息"]
                
                # 在主线程中更新UI
                self.root.after(0, lambda: self.update_results(results))
                
                # 清空输入框
                self.root.after(0, lambda: self.search_entry.delete(0, tk.END))
                
            except asyncio.TimeoutError:
                self.root.after(0, lambda: self.update_results(["查询超时，请稍后再试"]))
            except Exception as e:
                error_msg = f"查询处理错误: {str(e)}"
                print(error_msg)
                self.root.after(0, lambda: self.update_results([error_msg]))
            
        except Exception as e:
            error_msg = f"执行查询错误: {str(e)}"
            print(error_msg)
            self.root.after(0, lambda: self.update_results([error_msg]))

    def update_results(self, results):
        """更新结果区域，支持Markdown格式"""
        # 停止进度条
        self.progress_bar.stop()
        self.progress_frame.pack_forget()
        
        # 启用搜索按钮
        self.search_button.config(state="normal")
        
        # 清空现有内容
        self.result_text.delete(1.0, tk.END)
        
        # 显示结果，处理Markdown格式
        formatted_text = ""
        for result in results:
            if not result.strip():  # 跳过空行
                continue
                
            # 清理Markdown格式
            cleaned_text = self.clean_markdown(result)
            
            # 处理Markdown格式
            self.insert_formatted_text(cleaned_text)
            self.result_text.insert(tk.END, "\n\n")
    
    def clean_markdown(self, text):
        """清理文本中的Markdown标记"""
        # 移除星号标记
        text = re.sub(r'\*\*(.*?)\*\*', r'\1', text)  # 移除双星号
        text = re.sub(r'\*(.*?)\*', r'\1', text)      # 移除单星号
        
        # 移除下划线标记
        text = re.sub(r'__(.*?)__', r'\1', text)
        text = re.sub(r'_(.*?)_', r'\1', text)
        
        # 处理其他可能的Markdown标记...
        
        return text
    
    def insert_formatted_text(self, text):
        """将格式化后的文本插入到结果区域"""
        # 处理标题
        if text.startswith('#'):
            count = 0
            for char in text:
                if char == '#':
                    count += 1
                else:
                    break
            
            if count > 0 and count <= 6:
                title_text = text[count:].strip()
                self.result_text.insert(tk.END, title_text, "header")
                return
        
        # 检查是否是表单项，如"航空公司："等格式
        if "：" in text or ": " in text:
            # 分割字符串，分为标题和内容
            parts = []
            if "：" in text:
                title, content = text.split("：", 1)
            elif ": " in text:
                title, content = text.split(": ", 1)
            else:
                # 处理一般文本
                self.result_text.insert(tk.END, text)
                return
                
            # 直接显示标题部分，不加粗
            self.result_text.insert(tk.END, title + "：", "normal")
            
            # 内容部分
            self.result_text.insert(tk.END, content, "normal")
            return
        
        # 一般文本
        self.result_text.insert(tk.END, text, "normal")

    def on_closing(self):
        """关闭窗口时清理资源"""
        global manager, loop
        try:
            if loop and manager:
                # 在事件循环中关闭manager
                try:
                    close_future = asyncio.run_coroutine_threadsafe(manager.aclose(), loop)
                    close_future.result(timeout=2.0)  # 2秒超时
                except Exception as e:
                    print(f"关闭manager错误: {str(e)}")
                
                # 停止事件循环
                try:
                    if loop.is_running():
                        loop.call_soon_threadsafe(loop.stop)
                        time.sleep(0.5)  # 等待事件循环停止
                except Exception as e:
                    print(f"停止事件循环错误: {str(e)}")
        except Exception as e:
            print(f"关闭资源错误: {str(e)}")
        finally:
            self.root.destroy()

if __name__ == "__main__":
    try:
        root = tk.Tk()
        app = FlySearchApp(root)
        root.mainloop()
    except Exception as e:
        print(f"应用程序错误: {str(e)}")
    finally:
        # 尝试关闭事件循环
        try:
            if loop:
                if loop.is_running():
                    loop.call_soon_threadsafe(loop.stop)
                    time.sleep(0.5)
                loop.close()
        except Exception as e:
            print(f"关闭事件循环错误: {str(e)}")
